package com.dyx.resource;


import java.net.URL;

/**
 * 1.资源文件是否在跟类同级的package下
 * 2.获取资源的方式是哪种，比如通过Classloader去获取还是直接Class方式获取。
 * Resource test
 *
 * @author dengyouxu
 * @date 2021.07.20 13:01:11:956
 */
@SuppressWarnings("ALL")
public class ResourceTest {

    public static void main(String[] args) {
//        getResourceByClass();
        getResourceByClass1();
//        getResourceByClassloader();
    }

    /**
     * Class.getResource(String path)
     * path不以’/'开头时，默认是从此类所在的包下取资源；
     * path  以’/'开头时，则是从ClassPath根下获取；
     * <p>
     *
     *
     * Class.getResource()其实就会调用该类的ClassLoader的getResource()方法，但是多做了一步resolveName(name)
     *
     * 逻辑如下:
     * 1. 如果传入的那么name以"/"开头，则会把"/"去掉，会只保留文件名称部分
     * 2. 否则获取当前加载类的完整的类路径baseName，即包名.类名，如我这里是com.dyx.resource.ResourceTest，
     * 通过取baseName的最后一个"."的index，通过baseName.substring(0, index)取到包名，将"."替换为"/"，再拼接上资源名称
     * <pre>
     * int index = baseName.lastIndexOf('.');//找到文件的包名称
     * if (index != -1) {
     *     // 将包名称中的.替换为/ 并在最后加上/ 文件名
     *     name = baseName.substring(0, index).replace('.', '/') +"/" +name;
     * }
     * </pre>
     *
     * Gets resource by class
     *
     * @author dengyouxu
     * @date 2021.07.20 12:26:19:293
     * @see Class#getResource(java.lang.String)
     * @see Class#resolveName(java.lang.String)
     */
    private static void getResourceByClass() {
        System.out.println(ResourceTest.class.getResource(""));

        // 这种方式就相当于ResourceTest.class.getClassLoader().getResource(""))
        System.out.println(ResourceTest.class.getResource("/"));
    }

    /**
     * 如果
     */
    private static void getResourceByClass1() {
        // file:/Users/dengyouxu/Developer/WorkSpace/OpenSourceWorkSpace/Tomcat-Source-Code-Analysis/ClassloaderDemo/target/classes/com/dyx/resource/test1.txt
        final URL url1_1 = ResourceTest.class.getResource("/com/dyx/resource/test1.txt");

        // null
        final URL url1_2 = ResourceTest.class.getResource("com/dyx/resource/test1.txt");

        // null
        final URL url1_3 = ResourceTest.class.getResource("/test1.txt");

        // file:/Users/dengyouxu/Developer/WorkSpace/OpenSourceWorkSpace/Tomcat-Source-Code-Analysis/ClassloaderDemo/target/classes/com/dyx/resource/test1.txt
        final URL url1_4 = ResourceTest.class.getResource("test1.txt");

        System.out.println("url1_1-->" + url1_1);
        System.out.println("url1_2-->" + url1_2);
        System.out.println("url1_3-->" + url1_3);
        System.out.println("url1_4-->" + url1_4);
        System.out.println("==========分隔符==========");

        // file:/Users/dengyouxu/Developer/WorkSpace/OpenSourceWorkSpace/Tomcat-Source-Code-Analysis/ClassloaderDemo/target/classes/com/dyx/test2.txt
        final URL url2_1 = ResourceTest.class.getResource("/com/dyx/test2.txt");

        // null
        final URL url2_2 = ResourceTest.class.getResource("com/dyx/test2.txt");

        System.out.println("url2_1-->" + url2_1);
        System.out.println("url2_2-->" + url2_2);
        System.out.println("==========分隔符==========");

        // file:/Users/dengyouxu/Developer/WorkSpace/OpenSourceWorkSpace/Tomcat-Source-Code-Analysis/ClassloaderDemo/target/classes/test3.txt
        final URL url3_1 = ResourceTest.class.getResource("/test3.txt");

        // null
        final URL url3_2 = ResourceTest.class.getResource("test3.txt");

        System.out.println("url3_1-->" + url3_1);
        System.out.println("url3_2-->" + url3_2);

    }

    /**
     * path不能以’/'开头时；
     * path是从ClassPath根下获取；
     *
     * <pre>
     * public URL getResource(String name) {
     *     URL url;
     *     if (parent != null) {
     *         url = parent.getResource(name);
     *     } else {
     *         url = getBootstrapResource(name);
     *     }
     *     if (url == null) {
     *         url = findResource(name);
     *     }
     *     return url;
     * }
     * </pre>
     * 这里如果我们用的是 main 方法启动,那么当前的 classloader 就是AppClassloader,
     * parent 就是ExtClassloader, 这里无论从 parent 还是 bootstrapResource 都无法找到相对应的资源(通过 debug),
     * 那么这个返回值肯定是从 findResource(name) 中获得.
     *

     *
     * Gets resource by classloader
     *
     * @author dengyouxu
     * @date 2021.07.20 12:28:32:665
     */
    private static void getResourceByClassloader() {
        System.out.println(ResourceTest.class.getClassLoader().getResource(""));
        System.out.println(ResourceTest.class.getClassLoader().getResource("/"));
    }



}
